package com.victor.loading.book;

import com.victor.loading.ResourceTable;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.StackLayout;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;

import java.lang.ref.WeakReference;
import java.util.ArrayList;

/**
 * Book loading
 * Created by Victor on 15/7/28.
 */
public class BookLoading extends StackLayout {
    private static final String TAG = "BookLoading";

    private static final long DURATION = 1000;

    private static final int MSG = 1;

    private static final int PAGE_NUM = 5;

    private static final int DELAYED = 200;

    private ArrayList<PageView> pageViews;

    private BookHandler bookHandler;

    private boolean isStart;

    private AnimatorValue mAnimatorValue;

    public BookLoading(Context context) {
        super(context);
        initView(context);
    }

    public BookLoading(Context context, AttrSet attrs) {
        super(context, attrs);
        initView(context);
    }

    public BookLoading(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context);
    }

    private void initView(Context context) {
        Component component = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_book_loading, this, false);
        this.addComponent(component);
        pageViews = new ArrayList<>();
        bookHandler = new BookHandler(this);
        addPage();
    }

    private void addPage() {
        LayoutConfig params = new LayoutConfig(LayoutConfig.MATCH_PARENT, LayoutConfig.MATCH_PARENT);

        for (int i = 0; i < PAGE_NUM; i++) {
            PageView pageView = new PageView(getContext());
            addComponent(pageView, params);
            pageView.setTag(i);
            pageViews.add(pageView);
        }
    }

    private void playAnim() {
        setAnim(pageViews.get(PAGE_NUM - 1), DELAYED);

        setAnim(pageViews.get(PAGE_NUM - 1), DURATION + DELAYED);
        setAnim(pageViews.get(PAGE_NUM - 2), DURATION + DELAYED * 2);

        for (int i = PAGE_NUM - 1; i >= 0; i--) {
            setAnim(pageViews.get(i), DURATION * 3 + (PAGE_NUM - 1 - i) * DELAYED / 2);
        }
    }

    private void setAnim(final Component view, long delay) {
        mAnimatorValue = new AnimatorValue();
        mAnimatorValue.setDuration(DURATION);
        mAnimatorValue.setDelay(delay);

        mAnimatorValue.setCurveType(Animator.CurveType.LINEAR);
        mAnimatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            boolean change = false;
            @Override
            public void onUpdate(AnimatorValue animatorValue, float val) {
                ((PageView)view).updateValue(val);
                if (mAnimatorValue.getDuration() > DURATION / 2 && !change) {
                    change = true;
                    BookLoading.this.moveChildToFront(view);
                }
            }
        });

        mAnimatorValue.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {
                if ((int) view.getTag() == PAGE_NUM - 1) {
                    BookLoading.this.moveChildToFront(view);
                }
            }

            @Override
            public void onStop(Animator animator) { }

            @Override
            public void onCancel(Animator animator) { }

            @Override
            public void onEnd(Animator animator) { }

            @Override
            public void onPause(Animator animator) { }

            @Override
            public void onResume(Animator animator) { }
        });
        mAnimatorValue.start();
    }

    public void start() {
        isStart = true;
        bookHandler.sendEvent(InnerEvent.get(MSG));
    }

    public void stop() {
        isStart = false;
        bookHandler.removeEvent(MSG);
        bookHandler.removeAllEvent();
        mAnimatorValue.cancel();
        invalidate();
    }

    public boolean isStart() {
        return isStart;
    }

    static class BookHandler extends EventHandler {
        private WeakReference<BookLoading> weakReference;

        public BookHandler(BookLoading bookLoading) {
            super(EventRunner.getMainEventRunner());
            weakReference = new WeakReference<>(bookLoading);
        }

        @Override
        protected void processEvent(InnerEvent event) {
            super.processEvent(event);
            BookLoading bookLoading = weakReference.get();
            if(bookLoading == null) {
                return;
            }

            bookLoading.playAnim();
            InnerEvent message = InnerEvent.get(MSG);
            sendEvent(message, DURATION * 5);
        }
    }
}
